package main

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
	"path/filepath"
	"sync"
)

// func http download
func download(url string) (string, error) {
	resp, err := http.Get(url)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}
	return string(body), nil
}

func saveFile(filename string, content string) error {
	// 获取文件所在的目录路径
	dir := filepath.Dir(filename)

	// 检查目录是否存在，如果不存在则创建
	err := os.MkdirAll(dir, os.ModePerm)
	if err != nil {
		return err
	}

	file, err := os.Create(filename)
	if err != nil {
		return err
	}
	defer file.Close()

	_, err = file.WriteString(content)
	if err != nil {
		return err
	}
	return nil
}

func getFileFromOb(url string, filepath string) error {
	text, err := download(url)
	if err != nil {
		return err
	}
	err = saveFile(filepath, text)
	if err != nil {
		return err
	}
	return nil
}

type FileEntry struct {
	Path  string `json:"path"`
	Mtime int64  `json:"mtime"`
	Size  int    `json:"size"`
}

type FileEntries []FileEntry

func readOldSumJSON(path string) (FileEntries, error) {
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	var fileEntries FileEntries
	err = json.NewDecoder(file).Decode(&fileEntries)
	if err != nil {
		return nil, err
	}
	return fileEntries, nil
}

func downloadConcurrently(downloadList []FileEntry, path string, wg *sync.WaitGroup) {
	for _, item := range downloadList {
		wg.Add(1)
		go func(item FileEntry) {
			defer wg.Done()
			err := getFileFromOb("https://note.ftls.xyz/"+item.Path, path+item.Path)
			fmt.Println("Download " + item.Path)
			if err != nil {
				fmt.Println(err)
			}
		}(item)
	}
}

func compareLists(oldList, newList []FileEntry) (updated, deleted, added []FileEntry) {
	oldMap := make(map[string]FileEntry)
	newMap := make(map[string]FileEntry)

	// Fill the oldMap with the old list
	for _, entry := range oldList {
		oldMap[entry.Path] = entry
	}

	// Fill the newMap with the new list and check for updates
	for _, entry := range newList {
		newMap[entry.Path] = entry
		if oldEntry, exists := oldMap[entry.Path]; exists {
			// || 或关系
			if oldEntry.Mtime != entry.Mtime && oldEntry.Size != entry.Size {
				updated = append(updated, entry)
			} else if oldEntry.Size != entry.Size {
				updated = append(updated, entry)
			}
			delete(oldMap, entry.Path) // Remove from oldMap to find deletions later
		} else {
			added = append(added, entry)
		}
	}

	// The remaining items in oldMap are deletions
	for _, entry := range oldMap {
		deleted = append(deleted, entry)
	}

	return updated, deleted, added
}
